package com.ytf.test.seventh;

import java.util.Arrays;
import java.util.Random;

class Value{
   int i; // Package access

    public Value(int i) {
        this.i = i;
    }

    @Override
    public String toString() {
        return "Value{" +
                "i=" + i +
                '}';
    }
}

/**
 * @author: YTF
 * @date: 2024/11/26 11:25
 * @version: 1.0
 * @description:
 */
public class FinalData {
    private static Random rand = new Random(47);
    private String id;

    public FinalData(String id) {
        this.id = id;
    }
    // Can be compile-time constants
    private final int valueOne = 9;
    private static final int VALUE_TWO = 99;
    // Typical public constant
    private static final int VALUE_THREE = 39;
    // Cannot be compile-time constants
    private final int i4 = rand.nextInt(20);
    static final int INT_5 = rand.nextInt(20);
    private Value v1 = new Value(11);
    private final Value v2 = new Value(22);
    private static final Value VAL_3 = new Value(33);
    //Arrays:
    private final int[] a = {1,2,3,4,5,6};

    @Override
    public String toString() {
        return "FinalData{" +
                "id='" + id + '\'' +
                ", valueOne=" + valueOne +
                ", i4=" + i4 +
                ", v1=" + v1 +
                ", v2=" + v2 +
                ", a=" + Arrays.toString(a) +
                '}';
    }

    public static void main(String[] args) {
        FinalData fd1 = new FinalData("fd1");
        //! fd1.valueOne++; //Error: can't change value
        fd1.v2.i++; // Object isn't constant!
        fd1.v1 = new Value(9); // OK -- not final
        for (int i = 0; i < fd1.a.length; i++) {
            fd1.a[i]++; // Object isn't constant!
            //! fd1.v2 = new Value(0); // Error: Can't
            //! fd1.VAL_3 = new Value(1); // Cannot assign a value to final variable 'VAL_3'
            //! fd1.a = new int[3]; // Cannot assign a value to final variable 'a'
        }
        System.out.println(fd1);
        System.out.println("Creating new FinalData");
        FinalData fd2 = new FinalData("fd2");
        System.out.println(fd1);
        System.out.println(fd2);

        /**
         * Output:
         * FinalData{id='fd1', valueOne=9, i4=15, v1=Value{i=9}, v2=Value{i=23}, a=[2, 3, 4, 5, 6, 7]}
         * Creating new FinalData
         * FinalData{id='fd1', valueOne=9, i4=15, v1=Value{i=9}, v2=Value{i=23}, a=[2, 3, 4, 5, 6, 7]}
         * FinalData{id='fd2', valueOne=9, i4=13, v1=Value{i=11}, v2=Value{i=22}, a=[1, 2, 3, 4, 5, 6]}
         *
         * 总结：
         * 注意v2 和 数组a 虽然都使用了 final 但依旧可以改变值，但不能修改引用地址
         */
    }
}
